<?php
/**
 * Created by PhpStorm.
 *
 * @Date: 2017-08-24
 * @Time: 14:30
 * @Author: cdkay
 * @Email: network@iyuanma.net
 *
 * @File： Live.php
 */
namespace app\api\model\live;

use app\admin\model\ApiResponse;
use app\admin\model\live\LiveChannel;
use app\admin\model\SysAdmin;
use app\api\controller\App;
use app\api\model\LiveToken;
use app\common\model\app\ConstLinkType;
use app\common\model\BuyBill;
use app\common\model\Chat;
use app\common\lib\rongcloud\RongCloud;
use app\common\model\dynamic\DynamicFlowItem;
use app\common\model\dynamic\DynamicFlowItemTeacher;
use app\common\model\DynamicFlow;
use app\common\model\IMakeDynamicFlow;
use app\common\model\SysConfiguration;
use app\common\model\teacher\Teacher;
use app\common\model\UserNoticeMessage;
use library\JPushZDY;

use library\v163Class;
use think\Db;
use think\db\Query;
use think\Exception;
use think\Log;
use think\Model;
use think\Validate;

/**
 * Class Live
 * @package app\api\model\live
 *
 * @property integer id
 * @property string title
 * @property string cover
 * @property integer teacher_id
 * @property string introduce
 * @property integer status
 * @property string video_url
 * @property string live_date
 * @property string start_time
 * @property string end_time
 * @property string created
 * @property integer num_liked
 * @property integer duration
 * @property integer live_price
 * @property integer playback_price
 * @property integer live_channel_id
 * @property integer vid
 * @property integer number_online_peak
 * @property integer bind_curriculum_id
 * @property boolean is_encrypt  //true加密 false加密
 * @property string password
 *
 * Extension
 * @property bool free
 * @property integer buy_type
 * @property string share_url
 */
class Live extends Model implements IMakeDynamicFlow
{
    protected $table = 'live';
    protected $pk = 'id';

    const STATUS_INIT   = 0;
    const STATUS_START  = 1;
    const STATUS_END    = 2;
    const STATUS_RECORD = 3;
    public static $StatusNames = [
        self::STATUS_INIT   => '未开始',
        self::STATUS_START  => '正在直播',
        self::STATUS_END    => '已结束',
        self::STATUS_RECORD => '可回看',
    ];

    public static function setStatus($id, $status = self::STATUS_INIT) {
        return Db::execute('update live set status=:stat where id=:id', ['id'=>$id,'stat'=>$status]);
    }

    /**
     * isBuy
     * 查询当前登录用户是否购买直播节目
     *
     * @author zhengkai
     * @date 2017-11-14
     *
     * @param int $uid 用户id
     * @param int $liveId 直播节目id
     * @return int
     */
    private function isBuy($uid, $liveId)
    {
        if (SysAdmin::checkAdminUser($uid)) {
            return 1;
        }
        $live = Db::query("select live_price,playback_price from live where id={$liveId}");
        $live = $live[0];

        if (($live['live_price']>0) || ($live['playback_price']>0)) {
            $order = Db::query("select count(bill_id) as total from buy_bill where bill_item_type=2 and bill_user={$uid} and bill_have_paid='true'");
            $order = $order[0]['total'];

            if ($order) {
                return 1;
            } else {
                return 0;
            }
        } else {
            return 1; // 免费直播
        }
    }

    /**
     * 检查已购买
     *
     * @param $id
     * @return bool
     */
    public static function checkBeenBought($id) {
        $sql = 'SELECT exists( SELECT 1 FROM user_live_buy ulb WHERE ulb.live_id=:id LIMIT 1) e';
        $re = Db::query($sql, ['id' => $id]);
        return $re[0]['e'] ?? false;
    }

    /**
     * liveViewNumber
     * 直播在线观看人数计算
     *
     * @author zhengkai
     * @date 2018-01-29
     *
     * @param int $num
     * @return float|int
     */
    public static function liveViewNumber(int $num)
    {
        $num = $num??1;

        return $num * 1000 + rand(100, 999);
    }

    /**
     * liveStatus
     * 获取直播节目直播状态
     *
     * @author zhengkai
     * @date 2018-01-19
     *
     * @param int $liveId 直播id
     * @return static
     */
    public static function getSimple($liveId)
    {
        $data = self::get(function (Query $query) use ($liveId) {
            $query->where('id', $liveId);
            $query->field('id,status,live_channel_id');
        });

        return $data;
    }

    /**
     * get_live
     * 获取直播数据（当前正在直播节目、指定日期的节目列表）
     *
     * @author zhengkai
     * @date 2017-08-24
     *
     * @return \think\response\Json
     */
    public function get_live()
    {
        $uid = checkUserToken();

        /*** 获取当前正在直播的节目数据 ***/
        $live_current = $this
            ->alias('l')
            ->join('live_channel lc', 'l.live_channel_id=lc.id', 'LEFT')
            ->join('teacher t', 'l.teacher_id=t.id', 'LEFT')
            ->join('teacher_degree td', 't.degree_id=td.id', 'LEFT')
            ->where('l.live_date', date('Y-m-d', time()))
            ->where('l.status', self::STATUS_START)
            ->field(
                'l.id as live_id, 
                l.title as live_title, 
                l.introduce as live_info, 
                l.cover as live_cover, 
                l.live_price as live_price, 
                l.status as live_status, 
                t.id as teacher_id, 
                t.realname as teacher_name, 
                td.name as teacher_degree,
                t.avatar as teacher_avatar,
                t.intro as teacher_intro,
                t.num_followed as teacher_followed,
                t.followed,
                lc.pullurlhttp as live_http,
                lc.pullurlhls as live_hls,
                lc.pullurlrtmp as live_rtmp,
                lc.chat_room_id,
                lc.number_online as online_total,
                lc.online_num
            ')
            ->find();

        if ($live_current) { // *** 检查空值 ***
            $live_current = $live_current->toArray();

            $live_current['is_fee'] = $live_current['live_price']>0?1:0; // 直播是否收费标识

            $live_current['teacher_followed'] = countDataNum($live_current['teacher_followed'], $live_current['followed']);
            unset($live_current['followed']);

            if ($uid) { // 判断用户是否登录

                // 查询当前节目直播老师是否已被当前登录用户关注
                $follow_teacher = Db::table('user_follow_teacher')
                    ->where('userid', $uid)
                    ->where('teacher_id', $live_current['teacher_id'])
                    ->count();
                if ($follow_teacher) {
                    $live_current['is_follow_teacher'] = 1; // 已关注
                } else {
                    $live_current['is_follow_teacher'] = 0; // 未关注
                }

                // 查询当前登录用户是否已购买当前直播节目
                if ($live_current['is_fee']) { // 判断节目是否收费
                    $isBuy = Db::table('buy_bill')
                        ->where('bill_item_type', 2)
                        ->where('bill_item_id', $live_current['live_id'])
                        ->where('bill_user', $uid)
                        ->where('bill_have_paid', 'true')
                        ->count('bill_id');
                    if ($isBuy) {
                        $live_current['is_buy'] = 1; // 已购买
                    } else {
                        $live_current['is_buy'] = 0; // 未购买
                    }
                } else {
                    $live_current['is_buy'] = 1; // 免费直播默认为已购买状态
                }

            } else {
                $live_current['is_follow_teacher'] = 0; // 用户未登录默认为未关注
                $live_current['is_buy'] = 0; // 用户未登录默认为未购买
            }

            $live_current['live_info'] = stripHtml($live_current['live_info']);
            $live_current['teacher_intro'] = stripHtml($live_current['teacher_intro']);

            // 获取当前正在直播节目的在线观看人数，调用融云接口
//            $rc = RongCloud::getInstance()->Chatroom()->queryUser(Chat::getDefaultCharRoom(), 1, 1);

            // $live_current['online_total'] = (int)$rc['total']?((int)$rc['total'] * rand(100, 999)):rand(100, 999); // 当前在线人数
            // $live_current['online_total'] = self::liveViewNumber($live_current['online_total']); // 当前在线人数
            $live_current['online_total'] = countDataNum($live_current['online_total'], $live_current['online_num'], true); // 当前在线人数
            unset($live_current['online_num']);
//            $live_current['chat_room_id'] = Chat::getDefaultCharRoom();
        } else {
            $live_current = (object)array();
        }
        /*** 获取当前正在直播的节目数据 end ***/

        /*** 获取昨天、今天、明天直播节目数据 ***/
        $live_data = $this
            ->alias('l')
            ->join('live_channel lc', 'l.live_channel_id=lc.id', 'LEFT')
            ->join('teacher t', 'l.teacher_id=t.id', 'LEFT')
            ->join('teacher_degree td', 't.degree_id=td.id', 'LEFT')
            ->where('live_date', date('Y-m-d', time())) // 今天
            ->whereOr('live_date', date('Y-m-d', strtotime("-1 day"))) // 昨天
            ->whereOr('live_date', date('Y-m-d', strtotime("+1 day"))) // 明天
            ->field(
                'l.id as live_id, 
                l.title as live_title, 
                l.start_time as live_s_time, 
                l.end_time as live_e_time, 
                l.live_price as live_price, 
                l.playback_price as playback_price, 
                l.live_date as live_date, 
                l.status as live_status, 
                t.realname as teacher_name
            ')
            // ->order('l.live_date asc, l.start_time asc, l.id desc')
            // ->order('l.live_date asc, l.start_time asc')
            ->order('l.start_time asc')
            ->select();

        // 根据日期进行分组
        $day = [];
        foreach ($live_data as $d_key=>$d_val) {
            $day[$d_val['live_date']][] = $d_val;
        }

        // 按照日期分组遍历直播节目数据
        $live_list = [];
        foreach ($day as $key=>$val) {
            $day = '今天';
            if ($key<date('Y-m-d', time())) $day = '昨天';
            if ($key===date('Y-m-d', time())) $day = '今天';
            if ($key>date('Y-m-d', time())) $day = '明天';

            $list = [];
            foreach ($val as $l_key=>$l_val) {
                if ($l_val['live_price']>0 || $l_val['playback_price']>0) {
                    $l_val['is_fee'] = 1;
                } else {
                    $l_val['is_fee'] = 0;
                }

                if ($uid) { // 判断用户是否登录
                    if ($l_val['is_fee']) {
                        // 查询当前登录用户是否购买此直播节目
                        $isBuy = Db::table('buy_bill')
                            ->where('bill_item_type', 2)
                            ->where('bill_item_id', $l_val['live_id'])
                            ->where('bill_user', $uid)
                            ->where('bill_have_paid', 'true')
                            ->count('bill_id');
                        if ($isBuy) {
                            $l_val['is_buy'] = 1; // 已购买
                        } else {
                            $l_val['is_buy'] = 0; // 未购买
                        }
                    } else {
                        $l_val['is_buy'] = 1; // 如果是免费直播则默认为已购买
                    }

                    // 查询当前登录用户是否已预约直播节目
                    $make = Db::table('user_live_subscribe')
                        ->where('userid', $uid)
                        ->where('live_id', $l_val['live_id'])
                        ->count('id');
                    if ($make) {
                        $l_val['is_make'] = 1; // 已预约
                    } else {
                        $l_val['is_make'] = 0; // 未预约
                    }

                } else {
                    $l_val['is_buy'] = 0; // 如果用户未登录则默认为未购买
                    $l_val['is_make'] = 0; // 如果用户未登录则默认为未预约
                }

                $l_val['live_s_time'] = date('H:i', strtotime($l_val['live_s_time']));
                $l_val['live_e_time'] = date('H:i', strtotime($l_val['live_e_time']));

                $list[] = $l_val;
            }

            $live_list[] = [
                'day' => $day,
                'list' => $list
            ];

        }
        /*** 获取直播节目数据 end ***/

        $result = [
            'live_current' => $live_current, // 当前正在直接节目数据
            'live_list' => $live_list, // 直接节目数据
        ];

        return json(array('code'=>200, 'msg'=>'success', 'data'=>$result));
    }

    /**
     * get_live_detail
     * 获取直播(回看)详情数据
     *
     * @author zhengkai
     * @date 2017-08-24
     *
     * @param int $uid 用户id
     * @return \think\response\Json
     */
    public function get_live_detail($uid,$form)
    {
        $data = $this
            ->alias('l')
            ->join('live_channel lc', 'l.live_channel_id=lc.id', 'LEFT')
            ->join('teacher t', 'l.teacher_id=t.id', 'LEFT')
            ->join('teacher_degree td', 't.degree_id=td.id', 'LEFT')
            ->where('l.id', $form['live_id'])
            ->field(
                'l.id as live_id, 
                l.title as live_title, 
                l.introduce as live_info, 
                l.cover as live_cover, 
                l.live_price as live_price, 
                l.playback_price as playback_price, 
                l.num_liked as live_like_total, 
                l.video_url as live_playback_url, 
                l.status as live_status, 
                l.number_online_peak,
                lc.pullurlhttp as live_http, 
                lc.pullurlhls as live_hls, 
                lc.pullurlrtmp as live_rtmp, 
                t.id as teacher_id, 
                t.realname as teacher_name, 
                td.name as teacher_degree,
                t.avatar as teacher_avatar,
                t.intro as teacher_intro,
                t.num_followed as teacher_followed,
                t.followed,
                lc.chat_room_id,
                lc.number_online as online_total,
                lc.online_num
            ')
            ->find();
        if (empty($data))
            return json(array('code'=>1012, 'msg'=>'节目不存在', 'data'=>null));

        /*switch ($data['live_status']) {
            case 1:
                unset($data['live_playback_url']);
                break;
            case 2:
                unset($data['live_playback_url']);
                break;
            case 3:
                unset($data['live_http']);
                unset($data['live_hls']);
                unset($data['live_rtmp']);
                break;
            default :
                unset($data['live_playback_url']);
                unset($data['live_http']);
                unset($data['live_hls']);
                unset($data['live_rtmp']);
        }*/

        $data = $data->toArray();

        // 判断节目是否收费
        if ($data['live_price']>0 || $data['playback_price']>0) {
            // 查询当前登录用户是否购买此直播节目
            if (SysAdmin::checkAdminUser($uid)) {
                $isBuy = true;
            } else {
                $isBuy = Db::table('buy_bill')
                    ->where('bill_item_type', BuyBill::BUY_ITEM_LIVE)
                    ->where('bill_item_id', $form['live_id'])
                    ->where('bill_user', $uid)
                    ->where('bill_have_paid', 'true')
                    ->count('bill_id');
            }

            if (!$isBuy) {
                return json(array('code'=>1014, 'msg'=>'您还未购买此节目', 'data'=>null));
            }
        }

        // 查询当前直播节目老师是否被当前登录用户关注
        $follow_teacher = Db::table('user_follow_teacher')
            ->where('userid', $uid)
            ->where('teacher_id', $data['teacher_id'])
            ->count();
        if ($follow_teacher) {
            $data['is_follow_teacher'] = 1; // 已关注
        } else {
            $data['is_follow_teacher'] = 0; // 未关注
        }

        // 节目收费标识
        if ($data['live_price']>0 || $data['playback_price']>0) {
            $data['is_fee'] = 1;
        } else {
            $data['is_fee'] = 0;
        }

        $data['teacher_followed'] = countDataNum($data['teacher_followed'], $data['followed']);


        // 获取当前正在直播节目的在线观看人数，调用融云接口
//        $rc = RongCloud::getInstance()->Chatroom()->queryUser(Chat::getDefaultCharRoom(), 1, 1);

        // $data['online_total'] = (int)$rc['total']?((int)$rc['total'] * rand(100, 999)):rand(100, 999); // 当前在线人数
        if (self::STATUS_START != $data['live_status']) $data['online_total'] = $data['number_online_peak'];
        $online_total = $data['online_total']>0?($data['online_total']+$data['online_num']):$data['online_total'];
        $data['online_total'] = num2tring($online_total); // 当前在线人数
        unset($data['online_num']);
//        $data['chat_room_id'] = Chat::getDefaultCharRoom(); // 融云聊天室id

        $result = $data;

        return json(array('code'=>200, 'msg'=>'success', 'data'=>$result));
    }

    /**
     * query_live
     * 直播节目数据查询
     *
     * @author zhengkai
     * @data 2017-11-01
     * @version v1.1
     *
     * @param string $date 直播日期时间，格式：0000-00-00
     * @return \think\response\Json
     */
    public function query_live($date='')
    {
        // 查询当前正在直播的节目
        $toDay = date('Y-m-d', time());
        $sql = <<<SQL
select l.title,l.cover,t.realname from live as l
  left join teacher t on l.teacher_id=t.id
where l.live_date='{$toDay}' and l.status=1
SQL;
        $data = Db::query($sql);
        $currLive = $data?$data[0]:[];

        // 查询直播节目列表数据
        $date = empty($date) ? date('Y-m-d', time()) : $date;
        $sql = <<<SQL
select l.title,l.cover,l.start_time,l.end_time,t.realname from live as l
  left join teacher t on l.teacher_id=t.id
where l.live_date='{$date}'
order by l.start_time asc
SQL;
        $data = Db::query($sql);

        $list = [];
        foreach ($data as $key=>$val) {
            $val['start_time'] = date('H:i', strtotime($val['start_time']));
            $val['end_time'] = date('H:i', strtotime($val['end_time']));

            $list[] = $val;
        }

        $result = [
            'current' => $currLive,
            'list' => $list
        ];

        return json(array('code'=>200, 'msg'=>'success', 'data'=>$result));
    }

    /**
     * insert_live_make
     * 直播节目预约数据处理
     *
     * @author zhengkai
     * @date 2017-09-06
     *
     * @param int $uid 用户id
     * @return \think\response\Json
     */
    public function insert_live_make($uid)
    {
        $form = input('post.');

        // 表单验证
        $validate = new Validate([
            ['live_id', 'require|^\\d+$', '直播id不能为空|参数类型不正确']
        ]);
        if(!$validate->check($form)) return json(array('code'=>1010, 'msg'=>$validate->getError(), 'data'=>null));

        // 获取直播节目数据
        $live = $this->where('id', $form['live_id'])->find();
        if (!$live) return json(array('code'=>404, 'msg'=>'节目不存在', 'data'=>null));

        if ($live['live_date']==date('Y-m-d', time())) return json(array('code'=>1012, 'msg'=>'该节目不需要预约', 'data'=>null));

        // 查询直播节目是否已被预约
        $make = Db::table('user_live_subscribe')
            ->where('userid', $uid)
            ->where('live_id', $live['id'])
            ->count('id');
        if ($make) return json(array('code'=>1012, 'msg'=>'您已经预约过了！', 'data'=>null));

        $data = [
            'userid' => $uid,
            'live_id' => $live['id'],
            'subscribe_time' => time()
        ];

        $result = Db::table('user_live_subscribe')->insert($data);

        if ($result) {
            // 直播时间段
            $live_time_quantum = date('Y年m月d日', strtotime($live['live_date'])).' '.date('H:i', strtotime($live['start_time'])).'~'.date('H:i', strtotime($live['end_time']));

            // 自定义消息内容
            $serviceTel = SysConfiguration::getServiceTel(); // 客服电话
            $text = "您已经成功预约直播节目——{$live['title']}，直播时间{$live_time_quantum}。客服电话：{$serviceTel}";

            // 极光消息推送
            $extras = UserNoticeMessage::makeExtras(ConstLinkType::LINK_TYPE_LIVE, $live['id']);
            JPushZDY::pushUsers([$uid], $text, $extras);
            // 创建站内通知
            UserNoticeMessage::addMsg($uid,'直播消息', $text, $extras, UserNoticeMessage::MESSAGE_TYPE_SYSTEM);

            return json(array('code'=>200, 'msg'=>$text, 'data'=>null));
        } else {
            return json(array('code'=>1012, 'msg'=>"抱歉，预约失败！请重试或者联系客服。", 'data'=>null));
        }
    }

    /**
     * update_live_like
     * 更新直播节目点赞数据
     *
     * @author zhengkai
     * @date 2017-08-24
     *
     * @return \think\response\Json
     */
    public function update_live_like()
    {
        $form = input('post.');

        // 表单验证
        $validate = new Validate([
            ['live_id', 'require|^\\d+$', '直播id不能为空|参数类型不正确']
        ]);
        if(!$validate->check($form)) return json(array('code'=>1010, 'msg'=>$validate->getError(), 'data'=>null));

        $data = $this->where('id', $form['live_id'])->field('id, num_liked')->find()->toArray();

        $result = $this->where('id', $data['id'])->update(['num_liked'=>++$data['num_liked']]);

        if ($result) {
            $data = $this->where('id', $form['live_id'])->field('id, num_liked')->find()->toArray();

            return json(array('code'=>200, 'msg'=>'点赞成功', 'data'=>[
                'live_id'=>$data['num_liked'],
                'live_like_total'=>$data['num_liked']
            ]));
        } else {
            return json(array('code'=>1012, 'msg'=>'操作失败', 'data'=>null));
        }
    }

    /**
     * 首页的大咖播
     *
     * @return false|\PDOStatement|string|\think\Collection
     */
    public function get_live_list_index() {

        $live_date = date('Y-m-d');
        /*** 获取直播节目数据 ***/
        $live_data = $this
            ->alias('l')
            ->join('live_channel lc', 'l.live_channel_id=lc.id', 'LEFT')
            ->join('teacher t', 'l.teacher_id=t.id', 'LEFT')
            ->join('teacher_degree td', 't.degree_id=td.id', 'LEFT')
            ->where('live_date', $live_date)
            ->field(
                'l.id as live_id, 
                l.title as live_title, 
                l.start_time as live_s_time, 
                l.end_time as live_e_time, 
                l.status as live_status, 
                t.realname as teacher_name, 
                t.avatar as teacher_avatar
            ')
            ->order('l.start_time asc, l.id desc')
            ->select();
        foreach ($live_data as $key=>$val) {
            $live_data[$key]['live_s_time'] = date('H:i', strtotime($val['live_s_time']));
            $live_data[$key]['live_e_time'] = date('H:i', strtotime($val['live_e_time']));
        }
        /*** 获取直播节目数据 end ***/

        return $live_data;
        // return json(array('code'=>1012, 'msg'=>'操作失败', 'data'=>$live_data));
    }


    /**
     * get_buy_live
     * 获取用户已购买直播数据
     *
     * @author zhengkai
     * @date 2017-09-13
     *
     * @param int $uid 用户id
     * @param int $page 当前页数
     * @param int $rows 每页加载数据条数
     * @return \think\response\Json
     */
    public function get_buy_live($uid, $page=1, $rows=10)
    {
        $buy_live = Db::table('buy_bill')
            ->alias('bb')
            ->join('live l', 'bb.bill_item_id=l.id', 'LEFT')
            ->join('teacher t', 'l.teacher_id=t.id')
            ->where('bb.bill_user', $uid)
            ->where('bb.bill_item_type', 2)
            ->where('bb.bill_have_paid', 'true')
            ->field('
                l.id as live_id,
                l.title as live_title,
                l.status as live_status,
                l.live_date,
                l.start_time as live_start_time,
                l.start_time as live_end_time,
                t.realname as teacher_name
            ')
            ->order('live_date desc')
            ->page($page, $rows)
            ->select();

        $result = [];
        foreach ($buy_live as $kye=>$val) {
            $val['live_start_time'] = date('H:i', strtotime($val['live_start_time']));
            $val['live_end_time'] = date('H:i', strtotime($val['live_end_time']));

            $result[] = $val;
        }

        return json(array('code'=>200, 'msg'=>'success', 'data'=>$result));
    }

    public static function checkTimeRange($channelId, $startTime, $endTime, $liveId=0) {
        $data = Db::table('live')->where('live_channel_id', $channelId)
            ->where('start_time', 'BETWEEN', [$startTime, $endTime])
            ->where('end_time', 'BETWEEN', [$startTime, $endTime]);
        if ($liveId) $data->where('id', '<>', $liveId);
        $data = $data->count('id');

        if ($data) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 用于支付的方法，检查已购买
     *
     * @param $uid
     * @param $id
     * @return bool
     */
    public static function checkBought($uid, $id) {
        $sql = <<<SQL
SELECT exists(
  SELECT 1 FROM user_live_buy WHERE uid=:uid AND live_id=:id LIMIT 1
) e
SQL;
        $re = Db::query($sql, ['uid' => $uid, 'id' => $id]);
        return $re[0]['e'] ?? false;
    }

    /**
     * 用于支付的方法，计算商品总价格、获取商品信息等
     *
     * @param $uid
     * @param $live_id
     * @return array|bool
     */
    public static function getBuyInfo($uid, $live_id) {

        $live = self::get($live_id);
        if (empty($live)) return false;

        $teacher = Teacher::get($live->teacher_id);

        if ($live->status <= 1) {
            $price = $live->live_price;
        } else {
            $price = $live->playback_price;
        }

        // 优惠活动
        //

        return [
            'price_orig' => $price,
            'price' => $price,
            'title' => "直播《{$live->title}》",
            'detail' => $teacher->realname.' '.$live->live_date,
        ];
    }

    /**
     * 用于支付的方法，购买支付后的处理
     *
     * @param $bill_id
     * @param $uid
     * @param $live_id
     * @param BuyBill $bill
     */
    public static function afterBought($bill_id, $uid, $live_id, BuyBill $bill) {

        $sql = <<<SQL
INSERT INTO user_live_buy (uid, live_id) VALUES (:uid, :id)
SQL;
        Db::execute($sql, ['uid' => $uid, 'id' => $live_id]);

        $live = self::get($live_id);
        if ($live->status < 1) {
            // 直播未结束，则产生订阅
            $sql = <<<SQL
INSERT INTO user_live_subscribe (userid, live_id, subscribe_time, valid) 
VALUES (:userid, :live_id, :subscribe_time, TRUE )
ON CONFLICT DO NOTHING 
SQL;
            Db::execute($sql, [
                'userid' => $uid,
                'live_id' => $live_id,
                'subscribe_time' => time(),
            ]);
        }
    }

    public static function getSimpleList($ids) {
        return self::whereIn('id',$ids)->field('id,title')->select();
    }

    /**
     * 获取直播的频道id
     * @param $id
     * @return int
     */
    public static function getChannelId($id) {
        $sql = <<<SQL
SELECT live_channel_id cid FROM live WHERE id=:id
SQL;
        $re = Db::query($sql, ['id' => $id]);

        return intval($re[0]['cid'] ?? 0);
    }

    /**
     * getTodayLive
     * 获取当天直播节目数据
     *
     * @author zhengkai
     * @date 2017-11-14
     * @version 1.1
     *
     * @return \think\response\Json
     */
    public function getTodayLive($uid)
    {
        // 查询当前正在直播的节目
        $toDay = date('Y-m-d', time());
        $sql = <<<SQL
select 
    l.id as live_id,
    l.live_channel_id,
    l.title as live_title,
    l.cover as live_cover,
    l.num_liked as live_view,
    t.id as teacher_id,
    t.realname as teacher_name,
    t.avatar as teacher_avatar,
    t.intro as teacher_intro,
    t.num_followed as teacher_followed,
    t.followed,
    tt.name as teacher_degree,
    c.number_online online_total,
    c.chat_room_id,
    c.online_num
from live as l
  join live_channel c on l.live_channel_id=c.id
  left join teacher t on l.teacher_id=t.id
  left join teacher_degree tt on t.degree_id = tt.id
where l.live_date=:live_date and l.status=1
SQL;
        $data = Db::query($sql, ['live_date' => $toDay]);
        $data = $data[0] ?? null;

        if ($data) {
            // 查询当前直播节目老师是否被当前登录用户关注
            $follow_teacher = Db::table('user_follow_teacher')
                ->where('userid', $uid)
                ->where('teacher_id', $data['teacher_id'])
                ->count();
            if ($follow_teacher) {
                $data['is_follow_teacher'] = 1; // 已关注
            } else {
                $data['is_follow_teacher'] = 0; // 未关注
            }

            $data['teacher_followed'] = countDataNum($data['teacher_followed'], $data['followed']);
            unset($data['followed']);

            // $data['online_total'] = self::liveViewNumber($data['online_total']); // 当前在线人数
            $data['online_total'] = countDataNum($data['online_total'], $data['online_num'], true); // 当前在线人数
            unset($data['online_num']);
        }

        $currLive = $data?$data:(object)[];

        // 查询直播节目列表数据;
        $sql = <<<SQL
select 
    l.id as live_id,
    l.title as live_title,
    l.cover as live_cover,
    l.live_date,
    l.start_time as live_start_time, 
    l.end_time as live_end_time, 
    l.status as live_status,
    t.realname as teacher_name,
    t.avatar as teacher_avatar
from live as l
  left join teacher t on l.teacher_id=t.id
where l.live_date='{$toDay}'
order by l.start_time asc
SQL;
        $data = Db::query($sql);

        $list = [];
        foreach ($data as $key=>$val) {
            $val['live_start_time'] = date('H:i', strtotime($val['live_start_time']));
            $val['live_end_time'] = date('H:i', strtotime($val['live_end_time']));

            $list[] = $val;
        }

        $result = [
            'current' => $currLive,
            'list' => $list
        ];

        return json(array('code'=>200, 'msg'=>'success', 'data'=>$result));
    }

    /**
     * getSingleLive
     * 获取指定id的单个直播节目数据
     *
     * @author zhengkai
     * @date 2017-11-14
     * @version 1.1
     *
     * @param int $uid 用户id
     * @param int $liveId 直播节目id
     * @return \think\response\Json
     */
    public function getSingleLive($uid, $liveId)
    {
        $sql = <<<SQL
select 
  l.id as live_id,
  l.title as live_title,
  l.cover as live_cover,
  l.status as live_status,
  l.video_url as live_video_url,
  l.num_liked,
  t.id as teacher_id,
  t.realname as teacher_name,
  t.avatar as teacher_avatar,
  t.intro as teacher_intro,
  t.num_followed as teacher_followed,
  t.followed,
  tt.name as teacher_degree,
  lc.pullurlhttp as live_http,
  lc.pullurlhls as live_hls,
  lc.pullurlrtmp as live_rtmp,
  lc.chat_room_id,
  lc.number_online AS online_total,
  lc.online_num
from live as l
left join teacher t on l.teacher_id = t.id
left join teacher_degree tt on t.degree_id = tt.id
left join live_channel lc on l.live_channel_id=lc.id
where l.id={$liveId}
SQL;
        $data = Db::query($sql);

        $data = $data[0] ?? null;
        if (empty($data)) return json(array('code'=>1012, 'msg'=>'节目不存在', 'data'=>null));

        $isBuy = $this->isBuy($uid, $data['live_id']);
        if (!$isBuy) return json(array('code'=>1014, 'msg'=>'您还未购买该直播节目！', 'data'=>null));

        $data['live_video_url'] = $data['live_video_url']?:'';

        // 更新视频观看次数
        $view = ++$data['num_liked'];
        Db::query("update live set num_liked={$view} where id={$data['live_id']}");

        // 查询当前直播节目老师是否被当前登录用户关注
        $follow_teacher = Db::table('user_follow_teacher')
            ->where('userid', $uid)
            ->where('teacher_id', $data['teacher_id'])
            ->count();
        if ($follow_teacher) {
            $data['is_follow_teacher'] = 1; // 已关注
        } else {
            $data['is_follow_teacher'] = 0; // 未关注
        }


        $data['teacher_followed'] = countDataNum($data['teacher_followed'], $data['followed']);
        unset($data['followed']);

        // $data['online_total'] = self::liveViewNumber($data['online_total']); // 当前在线人数
        $data['online_total'] = countDataNum($data['online_total'], $data['online_num'], true); // 当前在线人数

        unset($data['num_liked'],$data['online_num']);

        $result = $data;
        return json(array('code'=>200, 'msg'=>'success', 'data'=>$result));
    }

    /**
     * playbackList
     * 直播视频回看列表
     *
     * @param int $page
     * @param int $rows
     * @param null $date
     * @param int $teacherId
     * @param int $channelId
     * @param int $uid
     * @param array $exclude
     * @return false|static[]
     */
    public static function playbackList($official,$page = 1, $rows = 10, $date = null, $teacherId = 0, $channelId = 0, $uid = 0, $exclude = null) {
        $condition['l.status']=self::STATUS_RECORD;
        if (is_array($exclude) && count($exclude)>0) $condition['l.id']=['not in',$exclude];
        if($date) $condition['l.live_date']=$date;
        if($teacherId > 0) $condition['l.teacher_id']=$teacherId;
        if($channelId > 0) $condition['l.live_channel_id']=$channelId;

        $list = self::alias('l')
            ->join('teacher t','t.id=l.teacher_id')
            ->join('live_channel cl','cl.id=l.live_channel_id','LEFT')
            ->where(function (Query $query) use ($condition,$official) {
                $query->where($condition);
                if($official){
                    $query->where('cl.official','=',$official);
                }
            })
          /*  ->order('l.live_date','desc')
            ->order('l.number_online_peak','desc')*/
            ->order('l.id','desc')
            ->field("l.id,l.title,l.cover,l.live_date,l.status,l.number_online_peak,l.replay_view,l.replay_num,l.live_price,l.playback_price,l.bind_curriculum_id,l.start_time,l.end_time,t.realname teacher_name,
                exists(select 1 from user_buy_curriculum ubc where ubc.uc_curriculum=l.bind_curriculum_id and ubc.uc_user=$uid) curriculum_has_bought")
            ->paginate($rows,false,['page'=>$page]);

        foreach ($list as $item) {
            $item->fixProperty();

            unset($item->replay_num);
        }

        return $list->toArray();
    }

    /**
     * playbackDetail
     * 直播视频回看详情
     *
     * @param $id
     * @param int $uid
     * @return Live|null
     * @throws \think\exception\DbException
     */
    public static function playbackDetail($id, $uid = 0,$token='') {
        $live = self::get(function (Query $query) use ($id, $uid) {
            $query->join('curriculum c','c.curriculum_id=bind_curriculum_id','LEFT');
            $query->where('id',$id);
            $query->where('status',self::STATUS_RECORD);
            $query->field("id,title,cover,status,introduce,video_url,duration,teacher_id,live_channel_id,bind_curriculum_id,live_price,playback_price,number_online_peak,replay_view,replay_num,is_encrypt,
            c.curriculum_name,
            exists(select 1 from user_buy_curriculum ubc where ubc.uc_curriculum=live.bind_curriculum_id and ubc.uc_user=$uid) curriculum_has_bought,
            exists(select 1 from user_live_buy ulb where ulb.live_id=id and ulb.uid={$uid}) live_has_bought");
        });
        if (is_null($live)) return null;

        // 更新直播视频回看数
        self::where('id', $id)->update(['replay_view'=>($live->replay_view+1)]);

        $live->replay_view = countDataNum($live->replay_view, $live->replay_num, true);

        $live->fixProperty();

        if($live->is_encrypt){
            if($token){
                $liveToken=LiveToken::getOne($token);
                if($liveToken){
                    $live->is_encrypt=false;
                }else{
                    $live->video_url='';
                }
            }else{
                $live->video_url='';
            }

        }

        unset($live->replay_num);

        return $live;
    }

    /**
     * playbackList
     * 直播视频回看列表
     *
     * @param int $page
     * @param int $rows
     * @param null $date
     * @param int $teacherId
     * @param int $channelId
     * @param int $uid
     * @param array $exclude
     * @return false|static[]
     */
    public static function relatedPlayBackList($page = 1, $rows = 10, $date = null, $teacherId = 0, $channelId = 0, $uid = 0, $exclude = null) {
        $list = self::all(function (Query $query) use ($page,$rows,$date,$teacherId,$channelId, $uid,$exclude) {
            $query->alias('l');
            $query->join('teacher t','t.id=l.teacher_id');
            $query->where('l.status',self::STATUS_RECORD);
            if (is_array($exclude) && count($exclude)>0) $query->whereNotIn('l.id', $exclude);
            if ($date) $query->where('l.live_date', $date);
            if ($teacherId > 0) $query->where('l.teacher_id', $teacherId);
            if ($channelId > 0) $query->where('l.live_channel_id', $channelId);
            //modify cc 2018-9-11
            $query->order('l.live_date','desc');
            //$query->order('l.number_online_peak','desc');
            //$query->order('l.id','desc');
            $query->page($page, $rows);
            $query->field("l.id,l.title,l.cover,l.live_date,l.start_time,l.end_time,l.status,l.number_online_peak,l.replay_view,l.replay_num,l.live_price,l.playback_price,l.bind_curriculum_id,t.realname teacher_name,
            exists(select 1 from user_buy_curriculum ubc where ubc.uc_curriculum=l.bind_curriculum_id and ubc.uc_user=$uid) curriculum_has_bought,
            exists(select 1 from user_live_buy ulb where ulb.live_id=l.id and ulb.uid={$uid}) live_has_bought
            ");
        });

        foreach ($list as $item) {
            $item->fixProperty();

            unset($item->replay_num);
        }
        return $list;
    }

    public function fixProperty() {

        // null 转为 0
        $this->bind_curriculum_id = $this->bind_curriculum_id ?? 0;
        // 根据条件设置类型
        if ($this->bind_curriculum_id > 0) {
            $this->buy_type = 2;
            $this->has_bought = $this->curriculum_has_bought;
        } else {
            $free = false;
            if (self::STATUS_START == $this->status || self::STATUS_INIT == $this->status) {
                $free = (0 == $this->live_price);
            } elseif (self::STATUS_RECORD == $this->status || self::STATUS_END == $this->status) {
                $free = (0 == $this->playback_price);
            }
            if ($free) {
                $this->buy_type = 0;
            } else {
                //fix bug,judgement live_has_bought exist
                if(isset($this->live_has_bought)){
                    $this->has_bought = $this->live_has_bought;
                }else{
                    $this->has_bought = false;
                }
                $this->buy_type = 1;
            }
        }
        //fix bug,judgement live_has_bought exist
        if(isset($this->live_has_bought)){
            unset($this->curriculum_has_bought, $this->live_has_bought);
        }else{
            unset($this->curriculum_has_bought);
        }

        if (isset($this->start_time)) $this->start_time = substr($this->start_time,11,5);
        if (isset($this->end_time)) $this->end_time = substr($this->end_time,11,5);

        // 用详情模拟摘要
        if (isset($this->introduce)) $this->summary = stripHtml($this->introduce);
        // 假数据，😳
        // if (isset($this->number_online_peak)) self::liveViewNumber($this->number_online_peak);
        if (isset($this->number_online_peak)) $this->number_online_peak = num2tring($this->number_online_peak);
        if (isset($this->replay_view)) $this->replay_view = countDataNum($this->replay_view, $this->replay_num, true);

        // 分享链接
        $this->share_url = self::shareUrl($this->id);
    }

    public static function shareUrl($id) {
        return sprintf('%s/live/previousPlay/%d',config('server.wapHost'), $id);
    }

    /**
     * 产生老师动态
     *
     * @param bool $isNew
     * @param integer $source
     * @return DynamicFlow
     * @throws Exception
     */
    public function makeDynamicData(bool $isNew, int $source = DynamicFlow::SOURCE_SYSTEM): DynamicFlow
    {
        $teacher = Teacher::get($this->teacher_id);
        if (empty($teacher)) {
            throw new Exception('数据错误，不正确的老师id');
        }

        $dynamic = new DynamicFlow();
        $dynamic->df_time = time();
        $dynamic->df_source = $source;
        $dynamic->df_isfee = false;
        $dynamic->df_isnew = $isNew;

        $item = new DynamicFlowItem();
        $item->item_id = (int) $this->id;
        $item->item_title = $this->title;
        $item->item_cover = $this->cover;
        $item->item_summary = stripHtml($this->introduce);

        $item_teacher = new DynamicFlowItemTeacher();
        $item_teacher->teacher_id = (int) $teacher->id;
        $item_teacher->teacher_name = $teacher->realname;
        $item_teacher->teacher_avatar = $teacher->avatar ?? Teacher::DEFAULT_AVATAR;
        $item_teacher->teacher_degree = $teacher->getDegreeName();
        $item->item_teacher = $item_teacher;

        $dynamic->df_class = DynamicFlow::CLASS_LIVE;
        $dynamic->df_type = DynamicFlow::TYPE_LIVE;

        $dynamic->df_value = $item;

        $dynamic->save();

        return $dynamic;
    }

    /**
     * getNewPlayLive
     * 获取最新的直播节目（无论正在直播或回看）
     *
     * @author zhengkai
     * @date 2018-04-23
     *
     * @return false|static[]
     * @throws \think\exception\DbException
     */
    public static function getNewPlayLive(){
        $data = self::get(function ($query) {
            $query->alias('l');
            $query->join('live_channel lc', 'l.live_channel_id=lc.id', 'left');
            $query->field('l.id, l.title, l.cover, l.status, l.video_url, l.live_channel_id, lc.pullurlhttp, lc.pullurlhls, lc.pullurlrtmp');
            $query->where('l.live_price', 0);
            $query->where('l.playback_price', 0);
            $query->where('l.status','in',[1,3]);
            $query->whereNull('l.bind_curriculum_id');
            $query->order('l.start_time desc, l.number_online_peak desc, lc.number_online desc');
        });

        return $data;
    }

    /**
     * getChannelLive
     * 获取指定直播频道id的直播节目数据(七天以内的)
     *
     * @author zhengkai
     * @date 2018-04-23
     *
     * @param int $channelId 频道id
     * @param int|null $filterLiveId 需要过滤的直播节目id(不需要出现在列表中的直播节目)
     * @return false|static[]
     * @throws \think\exception\DbException
     */
    public static function getChannelLive($channelId, $filterLiveId=null)
    {
        // $weekDay = App::week_calendar()->getData()['data'];
        // $startDay = $weekDay[0]['date'];
        // $endDay = end($weekDay)['date'];
        $now = time();
        $startDay = date('Y-m-d', strtotime('-10 days'));
        $endDay = date('Y-m-d', $now);
        $data = self::all(function ($query) use ($channelId, $filterLiveId, $startDay, $endDay) {
            $query->alias('l');
            $query->join('teacher t', 'l.teacher_id=t.id', 'left');
            $query->where('l.live_channel_id', $channelId);
            $query->where('live_date', 'BETWEEN', [$startDay, $endDay]);
            $query->field('l.id, l.title, l.status, t.realname as teacher_name');
            if (!is_null($filterLiveId)) $query->where('l.id', '<>', $filterLiveId);
            $query->order('l.start_time desc');
        });

        return $data;
    }

    public static function getOne($live_id,$field='*'){
        $live=self::where('id',$live_id)->field($field)->find();
        return $live;
    }
}
